package com.hottv.meeting.videomeeting.module.white;

import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.ColorRes;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.herewhite.sdk.AbstractRoomCallbacks;
import com.herewhite.sdk.Environment;
import com.herewhite.sdk.Logger;
import com.herewhite.sdk.Room;
import com.herewhite.sdk.RoomParams;
import com.herewhite.sdk.WhiteBroadView;
import com.herewhite.sdk.WhiteSdk;
import com.herewhite.sdk.WhiteSdkConfiguration;
import com.herewhite.sdk.domain.AkkoEvent;
import com.herewhite.sdk.domain.Appliance;
import com.herewhite.sdk.domain.BroadcastState;
import com.herewhite.sdk.domain.DeviceType;
import com.herewhite.sdk.domain.ImageInformationWithUrl;
import com.herewhite.sdk.domain.MemberState;
import com.herewhite.sdk.domain.Point;
import com.herewhite.sdk.domain.PptPage;
import com.herewhite.sdk.domain.Promise;
import com.herewhite.sdk.domain.RoomMouseEvent;
import com.herewhite.sdk.domain.RoomPhase;
import com.herewhite.sdk.domain.RoomState;
import com.herewhite.sdk.domain.SDKError;
import com.herewhite.sdk.domain.Scene;
import com.herewhite.sdk.domain.UrlInterrupter;
import com.herewhite.sdk.domain.ViewMode;
import com.hottv.meeting.videomeeting.common.MeetingConfig;
import com.hottv.meeting.videomeeting.module.meeting.MeetingManager;

import org.json.JSONObject;

import java.io.IOException;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.sql.Time;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

/**
 * Created by chengwenqiang on 2019/5/30.
 */

public class WhiteUtils {


    //获取颜色值
    public static int getColor(Context context, @ColorRes int resId) {
        return ContextCompat.getColor(context, resId);
    }


    public static String getMimeType(String path) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(path);
        if (contentTypeFor == null) {
            contentTypeFor = "application/octet-stream";
        }
        return contentTypeFor;
    }

    public static void getPNG(String url,String filePath,final DoCallback doCallback)
    {
        WhiteAPI.getInstance().uploadFile(url,filePath, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(MeetingConfig.TAG,e.getMessage());
                if(doCallback!=null)
                    doCallback.onFailor("uploadFile failor!!!!!!");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.code() == 200) {
                    JsonObject room = new Gson().fromJson(response.body().string(), JsonObject.class);
                    String urlStorage = room.getAsJsonObject("data").get("url").getAsString();
                    Log.i(MeetingConfig.TAG,"url:"+urlStorage);
                    getDocumentConvertInfo(urlStorage,"test",doCallback);
                }
                else
                {
                    Log.e(MeetingConfig.TAG,"get url  failor:");
                    if(doCallback!=null)
                        doCallback.onFailor("uploadFile failor code not ok");
                }
            }
        });
    }

    public static void getDocumentConvertInfo(String sourceUrl,String folder,final DoCallback doCallback)
    {
        WhiteAPI.getInstance().documentToPNG(sourceUrl, folder, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(MeetingConfig.TAG,e.getMessage());
                if(doCallback!=null)
                    doCallback.onFailor("documentToPNG failor!!!");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.code() == 200) {
                    JsonObject room = new Gson().fromJson(response.body().string(), JsonObject.class);
                    final  String taskUUID = room.getAsJsonObject("msg").get("taskUUID").getAsString();
                    boolean succeed = room.getAsJsonObject("msg").get("succeed").getAsBoolean();
                    Log.i(MeetingConfig.TAG,"taskUUID:"+taskUUID+",succeed:"+String.valueOf(succeed));

                    getTaskIdInfo(taskUUID, 3000, new DoCallback() {
                        @Override
                        public void onSuccess(String info) {

                            JsonObject document = new Gson().fromJson(info, JsonObject.class);
                            JsonObject taskInfo = document.getAsJsonObject("msg").getAsJsonObject("task");
                            Log.i(MeetingConfig.TAG,"onSuccess task info:"+taskInfo.toString());

                            WhiteManager.getInstance().addDocumentJson(taskInfo);

                            if(doCallback!=null)
                                doCallback.onSuccess("");
                        }

                        @Override
                        public void onFailor(String info) {
                            if(doCallback!=null)
                                doCallback.onFailor("documentToPNG code is not ok");
                        }

                        @Override
                        public void onProcess(String info) {
                            JsonObject document = new Gson().fromJson(info, JsonObject.class);
                            JsonObject taskInfo = document.getAsJsonObject("msg").getAsJsonObject("task");
                            Log.i(MeetingConfig.TAG,"onProcess task info:"+taskInfo.toString());

                            WhiteManager.getInstance().addDocumentJson(taskInfo);

                            if(doCallback!=null)
                                doCallback.onProcess("");
                        }
                    });
                } else {
                    Log.e(MeetingConfig.TAG,"");
                    if(doCallback!=null)
                        doCallback.onFailor("documentToPNG code is not ok");
                }
            }
        });
    }

    private static Boolean isFirst= true;
    public static void getTaskIdInfo(final String taskUUID,final int timeDelay,final DoCallback doCallback)
    {
       final Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //do something
                Log.i(MeetingConfig.TAG,"getTaskIdInfo----------------------");
                WhiteAPI.getInstance().getDocumentInfo(taskUUID, new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.e(MeetingConfig.TAG,e.getMessage());
                        if(doCallback!=null)
                            doCallback.onFailor("getDocumentInfo failor!!!");
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        if (response.code() == 200) {
                            String strTemp = response.body().string();
                            JsonObject document = new Gson().fromJson(strTemp, JsonObject.class);
                            JsonObject taskInfo = document.getAsJsonObject("msg").getAsJsonObject("task");

                            String staus = taskInfo.get("convertStatus").getAsString();
                            int processRate = taskInfo.get("convertedPercentage").getAsInt();
                            Log.i(MeetingConfig.TAG,"task info:"+taskInfo.toString());
//                                        WhiteManager.getInstance().addDocumentJson(taskInfo);

                            if(staus.equals("Fail"))
                            {
                                isFirst = true;
                                if(doCallback!=null) {
                                    doCallback.onFailor("is not ok");
                                    timer.cancel();
                                }
                            }
                            else if(staus.equals("Finished"))
                            {
                                isFirst = true;
                                if(doCallback!=null){
                                    doCallback.onSuccess(strTemp);
                                    timer.cancel();
                                }
                            }
                            else if(staus.equals("Converting"))
                            {
                                if(processRate>0 && (isFirst==true))
                                {
                                    isFirst = false;
                                    if(doCallback!=null){
                                        doCallback.onProcess(strTemp);
                                    }
                                }
                                getTaskIdInfo(taskUUID,timeDelay,doCallback);
                            }
//                                        Log.i(MeetingConfig.TAG,"taskInfo:"+taskInfo);
                        }else
                        {
                            Log.e(MeetingConfig.TAG,"getDocumentInfo failor!!!");
                            if(doCallback!=null)
                                doCallback.onSuccess("getDocumentInfo code is not ok");
                        }
                    }
                });
            }
        },timeDelay);//延时1s执行
    }

    //创建房间 获取房间的uuid 和 roomToken
    public static void createRoom(String roomName , final DoCallback callback)
    {
        Log.i(MeetingConfig.TAG,"createRoom");
        WhiteAPI.getInstance().createRoom(roomName, 100, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(MeetingConfig.TAG,"createRoom failor!!!");
                if(callback!=null)
                    callback.onFailor("createRoom failor!!!");
            }

            @Override
            public void onResponse(Call call, Response response) {
                try {
                    if (response.code() == 200) {
//                        JsonObject room = (new Gson()).fromJson(response.body().string(), JsonObject.class);
//                        String uuid = room.getAsJsonObject("msg").getAsJsonObject("room").get("uuid").getAsString();
//                        String roomToken = room.getAsJsonObject("msg").get("roomToken").getAsString();
//
                        if (callback!=null)
                        {
                            callback.onSuccess(response.body().string());
                        }
                    } else {
                        Log.e(MeetingConfig.TAG,"net request failor!!!body:"+response.body().string());
                        if(callback!=null)
                            callback.onFailor("createRoom failor!!!"+response.body().string());
                    }
                } catch (Throwable e) {
                    Log.e(MeetingConfig.TAG,"createRoom failor!!!Throwable:"+e.toString());
                    if(callback!=null)
                        callback.onFailor("createRoom failor!!!"+e.toString());
                }
            }
        });
    }

    //通过uuid获取roomToken
    public static void getRoomToken(final String uuid,final DoCallback callback)
    {
        WhiteAPI.getInstance().getRoomToken(uuid, new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.e(MeetingConfig.TAG, "createRoom failor!!!");
                        if (callback != null)
                            callback.onFailor("createRoom failor!!!");
                    }

                    @Override
                    public void onResponse(Call call, Response response) {
                        try {

                            if (response.code() == 200) {
                                JsonObject room = new Gson().fromJson(response.body().string(), JsonObject.class);
                                String roomToken = room.getAsJsonObject("msg").get("roomToken").getAsString();
                                if (callback != null) {
                                    callback.onSuccess(roomToken);
                                }
                            } else {
                                Log.e(MeetingConfig.TAG, "net request failor!!!body:" + response.body().string());
                                if (callback != null)
                                    callback.onFailor("createRoom failor!!!" + response.body().string());
                            }
                        } catch (Throwable e) {
                            Log.e(MeetingConfig.TAG, "createRoom failor!!!Throwable:" + e.toString());
                            if (callback != null)
                                callback.onFailor("createRoom failor!!!" + e.toString());
                        }
                    }
                });
    }

    //加入房间
    public static void joinRoom(Context context,String uuid, String roomToken, WhiteBroadView whiteView,Promise<Room> promise)
    {
        Log.i(MeetingConfig.TAG,"room uuid: " + uuid + "roomToken" + roomToken);

        WhiteSdkConfiguration sdkConfiguration = new WhiteSdkConfiguration(DeviceType.touch, 10, 0.1, true);
        /*显示用户头像*/
        sdkConfiguration.setUserCursor(true);
        /*接受用户头像信息回调，自己实现头像回调。会导致 UserCursor 设置失效。*/
        sdkConfiguration.setCustomCursor(true);

        WhiteSdk whiteSdk = new WhiteSdk(
                whiteView,
                context,
                sdkConfiguration,
                new UrlInterrupter() {
                    @Override
                    public String urlInterrupter(String sourceUrl) {
                        return sourceUrl;
                    }
                });

        whiteSdk.joinRoom(new RoomParams(uuid, roomToken), new AbstractRoomCallbacks() {
            @Override
            public void onPhaseChanged(RoomPhase phase) {

                Log.i(MeetingConfig.TAG,"onRoomStateChanged "+phase.name());

            }

            @Override
            public void onRoomStateChanged(RoomState modifyState) {
//                Log.i(MeetingConfig.TAG,"onRoomStateChanged "+new Gson().toJson(modifyState));

            }
        }, promise);
    }

    //广播
    public static void broadcast(Room room) {
        logAction();
        room.setViewMode(ViewMode.Broadcaster);
    }

    //获取广播状态
    public static void getBroadcastState(Room room) {
        logAction();
        room.getBroadcastState(new Promise<BroadcastState>() {
            @Override
            public void then(BroadcastState broadcastState) {

                logRoomInfo(new Gson().toJson(broadcastState));
            }

            @Override
            public void catchEx(SDKError t) {

            }
        });
    }

    //分发事件
    public static void dispatchCustomEvent(Room room) {
        logAction();
        HashMap payload = new HashMap<>();
        payload.put("device", "android");

        room.dispatchMagixEvent(new AkkoEvent(MeetingConfig.EVENT_NAME, payload));
    }

    public static void cleanScene(Room room) {
        logAction();
        room.cleanScene(false);
    }


    public static void insertNewScene(Room room) {
        logAction();
        room.putScenes(MeetingConfig.SCENE_DIR, new Scene[]{
                new Scene("page1")}, 0);
        room.setScenePath(MeetingConfig.SCENE_DIR + "/page1");
    }

    public static void insertPPTDemo(Room room) {
        logAction();

        room.putScenes(MeetingConfig.SCENE_DIR, new Scene[]{
                new Scene("page2", new PptPage("https://white-pan.oss-cn-shanghai.aliyuncs.com/101/image/alin-rusu-1239275-unsplash_opt.jpg", 600d, 600d))
        }, 0);
        room.setScenePath(MeetingConfig.SCENE_DIR + "/page2");
    }

    public static void insertPPT(Room room,Scene[] scenes,int index) {
        logAction();

        room.putScenes(MeetingConfig.SCENE_DIR,scenes, index);
        room.setScenePath(MeetingConfig.SCENE_DIR + "/page2");
    }


    public static void selectPPt(String select,Room room)
    {
        logAction();
        room.setScenePath(MeetingConfig.SCENE_DIR + "/"+select);
    }

    public static  void insertImage(Room room) {
        room.insertImage(new ImageInformationWithUrl(0d, 0d, 100d, 200d, "https://white-pan.oss-cn-shanghai.aliyuncs.com/40/image/mask.jpg"));
    }

    public static void getScene(Room room) {
        logAction();
        room.getScenes(new Promise<Scene[]>() {
            @Override
            public void then(Scene[] scenes) {
                logRoomInfo(new Gson().toJson(scenes));
            }

            @Override
            public void catchEx(SDKError t) {

            }
        });
    }

    public static void getRoomPhase(Room room) {
        logAction();
        room.getRoomPhase(new Promise<RoomPhase>() {
            @Override
            public void then(RoomPhase roomPhase) {
                logRoomInfo("RoomPhase: " + new Gson().toJson(roomPhase));

            }

            @Override
            public void catchEx(SDKError t) {

            }
        });
    }

    public static void getRoomState(Room room) {
        logAction();
        //获取房间状态，包含很多信息
        room.getRoomState(new Promise<RoomState>() {
            @Override
            public void then(RoomState roomState) {
                logRoomInfo("roomState: " + new Gson().toJson(roomState));
            }

            @Override
            public void catchEx(SDKError t) {

            }
        });
    }

    public static void disconnect(Room room) {

        //如果需要房间断开连接后回调
        room.disconnect(new Promise<Object>() {
            @Override
            public void then(Object o) {
                logAction("disconnect success");
            }

            @Override
            public void catchEx(SDKError t) {

            }
        });

        //如果不需要，则直接断开连接即可
        //room.disconnect();
    }

    public static void readonly(Room room) {
        logAction();
        room.disableOperations(true);
    }

    public static void disableReadonly(Room room) {
        logAction();
        room.disableOperations(false);
    }

    public static void pencil(Room room) {
        logAction();
        MemberState memberState = new MemberState();
        memberState.setStrokeColor(new int[]{99, 99, 99});
        memberState.setCurrentApplianceName(Appliance.PENCIL);
        memberState.setStrokeWidth(10);
        memberState.setTextSize(10);
        room.setMemberState(memberState);
    }

    public static void eraser(Room room) {
        logAction();
        MemberState memberState = new MemberState();
        memberState.setCurrentApplianceName(Appliance.ERASER);
        memberState.setStrokeWidth(20);
        room.setMemberState(memberState);
    }

    public static void rectangle(Room room) {
        logAction();
        MemberState memberState = new MemberState();
        memberState.setStrokeColor(new int[]{99, 99, 99});
        memberState.setCurrentApplianceName(Appliance.RECTANGLE);
        memberState.setStrokeWidth(10);
        memberState.setTextSize(10);
        room.setMemberState(memberState);
    }

    public static void setColorAndStroke(Room room,int color,int stroke) {
        logAction();
        MemberState memberState = new MemberState();
        memberState.setStrokeColor(new int[]{Color.red(color), Color.green(color), Color.blue(color)});
        memberState.setCurrentApplianceName(Appliance.PENCIL);
        memberState.setStrokeWidth(stroke);
        memberState.setTextSize(10);
        room.setMemberState(memberState);
    }

    public static void setColor(Room room,int color)
    {
        MemberState memberState = new MemberState();
        memberState.setStrokeColor(new int[]{Color.red(color), Color.green(color), Color.blue(color)});
        memberState.setCurrentApplianceName(Appliance.PENCIL);
        room.setMemberState(memberState);
    }

    public static void setStrokeWidth(Room room,int stroke)
    {
        MemberState memberState = new MemberState();
        memberState.setCurrentApplianceName(Appliance.PENCIL);
        memberState.setStrokeWidth(stroke);
        memberState.setTextSize(10);
        room.setMemberState(memberState);
    }

    public static void convertPoint(Room room) {
        //获取特定点，在白板内部的坐标点
        room.convertToPointInWorld(0, 0, new Promise<Point>() {
            @Override
            public void then(Point point) {
                logRoomInfo(new Gson().toJson(point));
            }

            @Override
            public void catchEx(SDKError t) {
                Logger.error("convertToPointInWorld  error", t);
            }
        });
    }

    public static void externalEvent(Room room) {
        logAction();
        room.disableOperations(true);
//        room.externalDeviceEventDown(new RoomMouseEvent(100, 300));
//        room.externalDeviceEventMove(new RoomMouseEvent(100, 400));
//        room.externalDeviceEventMove(new RoomMouseEvent(100, 500));
//        room.externalDeviceEventMove(new RoomMouseEvent(100, 600));
//        room.externalDeviceEventMove(new RoomMouseEvent(100, 700));
//        room.externalDeviceEventUp(new RoomMouseEvent(100, 700));
        room.disableOperations(false);
    }

    public static void zoomChange(final Room room,Promise<Number> promise)
    {
        room.getZoomScale(promise);
    }

    public static void zoomChange(final Room room, final double scale, final boolean isFoce) {
        room.getZoomScale(new Promise<Number>() {
            @Override
            public void then(Number number) {
                if(isFoce)
                {
                    Log.i(MeetingConfig.TAG,room.toString()+" zoomChange old:"+number.doubleValue()+",new:"+scale);
                    room.zoomChange(scale);
                }
                else
                {
                    if (number.intValue() == 1) {
                        Log.i(MeetingConfig.TAG,room.toString()+" zoomChange old:"+number.doubleValue()+",new:"+scale);
                        room.zoomChange(scale);
                    }
                }
            }

            @Override
            public void catchEx(SDKError t) {

            }
        });
    }

    public static void zoomChangeTo(final Room room, final double scale) {
        room.getZoomScale(new Promise<Number>() {
            @Override
            public void then(Number number) {
//                if (number.intValue() != 1) {
//                    room.zoomChange(1);
//                } else {
//                    room.zoomChange(5);
//                }
                Log.i(MeetingConfig.TAG,"zoomChangeTo old:"+number.doubleValue()+",new:"+scale);
                room.zoomChange(number.doubleValue()*scale);
            }

            @Override
            public void catchEx(SDKError t) {

            }
        });
    }
   public static void logRoomInfo(String str) {
        Log.i(MeetingConfig.TAG, Thread.currentThread().getStackTrace()[3].getMethodName() + " " + str);
    }

    public static void logAction(String str) {
        Log.i(MeetingConfig.TAG, Thread.currentThread().getStackTrace()[3].getMethodName() + " " + str);
    }

    public static void logAction() {
        Log.i(MeetingConfig.TAG, Thread.currentThread().getStackTrace()[3].getMethodName());
    }

}
